package com.yanfan.rs232;

import com.yanfan.common.annotation.SysProtocol;
import com.yanfan.common.constant.YanfanConstant;
import com.yanfan.common.core.mq.DeviceReport;
import com.yanfan.common.core.mq.MQSendMessageBo;
import com.yanfan.common.core.mq.message.DeviceData;
import com.yanfan.common.core.mq.message.FunctionCallBackBo;
import com.yanfan.common.core.thingsModel.ThingsModelSimpleItem;
import com.yanfan.iot.model.ThingsModels.ValueItem;
import com.yanfan.iot.service.impl.DeviceServiceImpl;
import com.yanfan.protocol.base.protocol.IProtocol;
import io.netty.buffer.ByteBuf;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Hex;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

@Slf4j
@Component
@SysProtocol(name = "耀华A9协议&AA", protocolCode = YanfanConstant.PROTOCOL.RS232_DESC, description = "耀华A9协议&AA")
public class Rs232_DescDescenDingMessageProtocol  implements IProtocol {

    @Autowired
    private RestapiMessage restapiMessage;

    @Autowired
    private DeviceServiceImpl deviceService;

    @Override
    public DeviceReport decode(DeviceData data, String clientId) {
        log.info("进入RS232倒序排列协议中......");
        DeviceReport report = new DeviceReport();
        //包装值的返回结果
        List<ThingsModelSimpleItem> thingsModelValueItemList = new ArrayList<>();
        ThingsModelSimpleItem thingsModelSimpleItem = new ThingsModelSimpleItem();
        ByteBuf in = data.getBuf();
        //首
        int start = in.getUnsignedByte(0);
        //尾
        int messageId = in.getUnsignedByte(in.writerIndex()-1);
        String StrRS232 = new String(data.getData(), StandardCharsets.UTF_8);
        log.error("=》进入RS232协议数据为【{}】",StrRS232);
        //注册包解析
        String substring1 = StrRS232.substring(0, 3);
        if(substring1.equals("&AA")){
            String substring = StrRS232.substring(3,StrRS232.length()-1);
            log.debug("=>客户端id[{}]",substring);
            report.setClientId(substring);
            report.setThingsModelSimpleItem(new ArrayList<>());
            report.setMessType("RS232");
            return report;
        }
        //心跳解析
        else if(start == 55 && messageId == 101){
            log.debug("=>心跳为{}:",StrRS232);
            report.setSerialNumber(clientId);
            report.setClientId(clientId);
            report.setThingsModelSimpleItem(new ArrayList<>());
            return report;
        }
        //数据解析
        else if(start == 2 && messageId == 3){
            log.info("数据报文为：【{}】",StrRS232);
            String reversed = StrRS232.substring(1, StrRS232.length() - 1);
            log.info("去除头和尾");
            //获取符合位置
            String substring = reversed.substring(0, 1);
            switch (substring){
                case "+":
                    String str = GETStr(reversed,data.getData(),"02");
                    if(!Objects.nonNull(str))
                        return null;
                    thingsModelSimpleItem.setValue(str);
                    break;
                case "-":
                    String string = GETStr(reversed,data.getData(),"02");
                    if(!Objects.nonNull(string))
                        return null;
                    thingsModelSimpleItem.setValue("-"+string);
                    break;
            }
            getValueItem(clientId,thingsModelSimpleItem);
            thingsModelValueItemList.add(thingsModelSimpleItem);
            report.setThingsModelSimpleItem(thingsModelValueItemList);
            report.setSerialNumber(clientId);
            report.setClientId(clientId);
            return report;
        }
        else{
            //获取前面4为标识
            if(StrRS232.contains("+LBS")){
                restapiMessage.LNGAndLAT(StrRS232,clientId);
            }
            else{
                log.error("错误报文：{}",StrRS232);
                String hexString = Hex.encodeHexString(data.getData());
                // 使用正则表达式(?i)来实现不区分大小写的分割
                String[] parts = hexString.split("(?i)02");
                String string = ListStrs(parts, "02");
                if (Objects.isNull(string)) {
                    return null;
                }
                else{
                    thingsModelSimpleItem.setValue(string);
                    getValueItem(clientId,thingsModelSimpleItem);
                    thingsModelValueItemList.add(thingsModelSimpleItem);
                    report.setThingsModelSimpleItem(thingsModelValueItemList);
                    report.setSerialNumber(clientId);
                    report.setClientId(clientId);
                    return report;
                }
            }
            report.setSerialNumber(clientId);
            report.setClientId(clientId);
            report.setThingsModelSimpleItem(new ArrayList<>());
            return report;
        }
    }

    @Override
    public FunctionCallBackBo encode(MQSendMessageBo message) {
        return null;
    }


    public static String GETStr(String reversed, byte[] data,String startStr){
        try {
            //获取数据结构
            String substring = reversed.substring(1, 7);
            log.info("获取数据符合的后6为数据：[{}]",substring);
            long num = Long.parseLong(substring);
            log.info("=>RS232正序解析上报的数据为：【{}】",num);
            String substring1 = reversed.substring(7, 8);
            log.info("=>获取小数为：【{}】",substring1);
            return calculateMultiplier(num, Integer.parseInt(substring1));
        } catch (NumberFormatException e) {
            log.error("=>数据解析：【{}】",reversed);
            String hexString = Hex.encodeHexString(data);
            // 使用正则表达式(?i)来实现不区分大小写的分割
            String[] parts = hexString.split("(?i)"+startStr);
            return ListStr(parts,startStr);
        }
    }

    /**
     * 获取最终结果解析
     * @param str 数据结构体
     * @param dou 小数位
     * @return
     */
    public static String calculateMultiplier(double str, int dou){
        BigDecimal bigDecimal = new BigDecimal(Math.pow(10, -dou));
        BigDecimal bigSet = bigDecimal.setScale(dou, BigDecimal.ROUND_HALF_UP);
        BigDecimal bigStr = new BigDecimal(str);
        BigDecimal result = bigStr.multiply(bigSet);
        return result.toString();
    }

    /**
     * 数据格式不对，重新解析
     */
    public static String ListStr(String[] parts,String startStr){
        // 遍历分割后的数组，将每个部分添加到List集合中
        for (String part : parts) {
            //字符串拼接
            String str = startStr+part.trim();
            if (str.length()==24) {
                try {
                    byte[] byteArray = Hex.decodeHex(part.trim()); // 解码为字节数组
                    if (str.substring(str.length() - 2, str.length()).equals("03")) {
                        // 将字节数组转换为ASCII字符串
                        String asciiString = new String(byteArray, StandardCharsets.US_ASCII);
                        //获取数据结构
                        String substring1 = asciiString.substring(1, 7);
                        long num = Long.parseLong(substring1);
                        String substring2 = asciiString.substring(7, 8);
                        return calculateMultiplier(num, Integer.parseInt(substring2));
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    public static String ListStrs(String[] parts,String startStr){
        // 遍历分割后的数组，将每个部分添加到List集合中
        for (String part : parts) {
            //字符串拼接
            String str = startStr+part.trim();
            if (str.length()==24) {
                try {
                    byte[] byteArray = Hex.decodeHex(part.trim()); // 解码为字节数组
                    String substring = part.trim().substring(0, 2);
                    if (str.substring(str.length() - 2, str.length()).equals("03")) {
                        // 将字节数组转换为ASCII字符串
                        String asciiString = new String(byteArray, StandardCharsets.US_ASCII);
                        //获取数据结构
                        String substring1 = asciiString.substring(1, 7);
                        long num = Long.parseLong(substring1);
                        String substring2 = asciiString.substring(7, 8);
                        String string = calculateMultiplier(num, Integer.parseInt(substring2));
                        return substring.equals("2d")?"-"+string:string;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    /**
     * 获取物模型
     */
    public void getValueItem(String clientId,ThingsModelSimpleItem thingsModelSimpleItem){
        //获取物模型
        List<ValueItem> valueItems = deviceService.selectValueItem(clientId);
        if (valueItems.size() == 1) {
            // 列表大小等于 1
            log.info("=>List contains exactly one element.");
            thingsModelSimpleItem.setId(valueItems.get(0).getId());
        } else {
            // 列表大小不等于 1（可能是 0 或多个）
            log.info("=>List does not contain exactly one element.");
            thingsModelSimpleItem.setId("weight");
        }
        thingsModelSimpleItem.setBit(false);
        thingsModelSimpleItem.setTs(new Date());
        log.error("=>客户端【{}】，物模型为：{}",clientId,valueItems);
    }
}
